package com.shop.loan.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.shop.loan.mapper.*;
import com.shop.loan.model.common.Code;
import com.shop.loan.model.common.ResResult;
import com.shop.loan.model.entity.*;
import com.shop.loan.model.enums.OrderStatus;
import com.shop.loan.model.enums.ReportType;
import com.shop.loan.model.enums.ServiceType;
import com.shop.loan.model.enums.UserStatus;
import com.shop.loan.model.vo.AddressCheckRes;
import com.shop.loan.model.vo.MachineRuleLogItemVo;
import com.shop.loan.model.vo.UserReportVo;
import com.shop.loan.rentaldata.RentalDataUtil;
import com.shop.loan.service.*;
import com.shop.loan.util.SysMsgUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import xyz.erupt.upms.util.IpUtil;

import javax.annotation.Resource;
import javax.transaction.Transactional;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.YearMonth;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class MachineRuleServiceImpl implements MachineRuleService {

    @Resource
    SettingService settingService;

    @Resource
    UserByMybatisMapper userByMybatisMapper;

    @Resource
    LoanOrderByMybatisMapper loanOrderByMybatisMapper;

    @Resource
    UserLoginLogByMybatisMapper userLoginLogByMybatisMapper;

    @Resource
    EruptUserByMybatisMapper eruptUserByMybatisMapper;

    @Resource
    EruptUserDataService eruptUserDataService;

    @Resource
    MsgService msgService;

    @Resource
    UserReportService userReportService;

    @Resource
    LoanOrderAuthByMybatisMapper loanOrderAuthByMybatisMapper;

    @Resource
    MachineRuleLogByMybatisMapper machineRuleLogByMybatisMapper;

    @Resource
    MachineRuleByMybatisMapper machineRuleByMybatisMapper;

    @Resource
    UserContactByMybatisMapper userContactByMybatisMapper;

    @Resource
    SysMsgUtil sysMsgUtil;

    @Lazy
    @Resource
    AsyncService asyncService;

    @Resource
    RentalDataUtil rentalDataUtil;

    @Async
    @Override
    public void createUpdateMachineReportByASync(Long userId) {
        ResResult resResult = createUpdateMachineReport(userId);
        log.info("机审结果：{}", JSON.toJSONString(resResult));
    }

    @Override
    public ResResult createUpdateMachineReport(Long userId) {
        if (userId == null) {
            return new ResResult(Code.FAIL);
        }
        UserByMybatis userByMybatis = userByMybatisMapper.selectByPrimaryKey(userId);
        if (userByMybatis == null || userByMybatis.getId() == null) {
            return new ResResult(Code.USER_LACK);
        }
        SettingByMybatis setting = settingService.getSetting();

        UserReportByMybatis reportByTanZ = null, reportByLeiDa = null;

        boolean stop = false;
        BigDecimal score = BigDecimal.valueOf(100);
        List<MachineRuleLogItemVo> machineRuleLogItems = new ArrayList<>();
        List<MachineRuleByMybatis> machineRuleList = machineRuleByMybatisMapper.selectByList();
        for (MachineRuleByMybatis machineRule : machineRuleList) {
            if (stop) {
                continue;
            }
            JSONObject reportJs = new JSONObject();
            if (machineRule.getReportType() == ReportType.TanZhenC.getType().intValue() && reportByTanZ == null) {
                reportByTanZ = getUserReport(machineRule.getReportType(), userByMybatis, setting);
                if (reportByTanZ == null) {
                    continue;
                }
            } else if (machineRule.getReportType() == ReportType.LeiDa.getType().intValue() && reportByLeiDa == null) {
                reportByLeiDa = getUserReport(machineRule.getReportType(), userByMybatis, setting);
                if (reportByLeiDa == null) {
                    continue;
                }
            }
            if (machineRule.getReportType() == 0) {
                reportJs = JSON.parseObject(JSON.toJSONString(userByMybatis));
            } else if (machineRule.getReportType() == ReportType.TanZhenC.getType().intValue()) {
                reportJs = JSON.parseObject(reportByTanZ.getInfoJson());
            } else if (machineRule.getReportType() == ReportType.LeiDa.getType().intValue()) {
                reportJs = JSON.parseObject(reportByLeiDa.getInfoJson());
            }

            MachineRuleLogItemVo machineRuleLogItem = new MachineRuleLogItemVo();
            machineRuleLogItem.setDesStr(machineRule.getRemark());
            machineRuleLogItem.setScore(BigDecimal.ZERO);
            machineRuleLogItem.setHitStatus(false);
            machineRuleLogItem.setNumber("");
            if (machineRule.getType() == 1 || machineRule.getType() == 2) {
                //数值>=
                boolean redirection = false;
                if (machineRule.getType() == 1) {
                    redirection = true;
                }
                String dataNum = compareData(new BigDecimal(machineRule.getDetail()), machineRule.getDataField(), reportJs, redirection);
                if (dataNum != null) {
                    score = score.subtract(machineRule.getSubScore());
                    machineRuleLogItem.setScore(machineRule.getSubScore());
                    machineRuleLogItem.setNumber(dataNum);
                    machineRuleLogItem.setHitStatus(true);
                } else {
                    machineRuleLogItem.setHitStatus(false);
                    machineRuleLogItem.setScore(BigDecimal.ZERO);
                }
                machineRuleLogItem.setDesStr(machineRule.getRemark());
            } else {
                if ("area_black".equals(machineRule.getRuleTag())) {
                    /**
                     * 区域黑名单
                     */
                    if (userByMybatis.getCardAddress() != null) {
                        AddressCheckRes addressCheckRes = checkArea(userByMybatis.getCardAddress(), machineRule.getDetail());
                        if (addressCheckRes != null) {
                            if (addressCheckRes.getType() == 2 && addressCheckRes.getScore() != null) {
                                //灰名单
                                machineRuleLogItem.setHitStatus(true);
                                machineRuleLogItem.setScore(addressCheckRes.getScore());
                                machineRuleLogItem.setNumber(addressCheckRes.getAddress());
                                score = score.subtract(machineRuleLogItem.getScore());
                            } else if (addressCheckRes.getType() == 3) {
                                //黑名单
                                machineRuleLogItem.setHitStatus(true);
                                machineRuleLogItem.setScore(machineRule.getSubScore());
                                machineRuleLogItem.setNumber(addressCheckRes.getAddress());
                                stop = true;
                                score = score.subtract(machineRuleLogItem.getScore());
                            }
                            if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                                stop = true;
                            }
                        }
                    }
                } else if ("location_area_black".equals(machineRule.getRuleTag())) {
                    /**
                     * 下单区域黑名单
                     */
                    LoanOrderByMybatis lastOrder = loanOrderByMybatisMapper.selectByLast(userByMybatis.getId());
                    if (lastOrder != null && StringUtils.hasLength(lastOrder.getLocationAddress())) {
                        AddressCheckRes addressCheckRes = checkArea(lastOrder.getLocationAddress(), machineRule.getDetail());
                        if (addressCheckRes != null) {
                            if (addressCheckRes.getType() == 2 && addressCheckRes.getScore() != null) {
                                //灰名单
                                machineRuleLogItem.setHitStatus(true);
                                machineRuleLogItem.setScore(addressCheckRes.getScore());
                                machineRuleLogItem.setNumber(addressCheckRes.getAddress());
                                score = score.subtract(machineRuleLogItem.getScore());
                            } else if (addressCheckRes.getType() == 3) {
                                //黑名单
                                machineRuleLogItem.setHitStatus(true);
                                machineRuleLogItem.setScore(machineRule.getSubScore());
                                machineRuleLogItem.setNumber(addressCheckRes.getAddress());
                                stop = true;
                                score = score.subtract(machineRuleLogItem.getScore());
                            }
                            if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                                stop = true;
                            }
                        }
                    }
                } else if ("ip_city_black".equals(machineRule.getRuleTag())) {
                    /**
                     * 用户所在ip黑名单
                     */
                    List<String> loginIpList = userLoginLogByMybatisMapper.selectIpByList(userByMybatis.getId());
                    loginIpList = loginIpList == null ? new ArrayList<>() : loginIpList;
                    List<String> orderIpList = loanOrderByMybatisMapper.selectIpByList(userByMybatis.getId());
                    if (orderIpList != null && orderIpList.size() > 0) {
                        loginIpList.addAll(orderIpList);
                    }

                    if (loginIpList.size() > 0) {
                        for (String ip : loginIpList) {
                            if (!StringUtils.hasLength(ip)) {
                                continue;
                            }
                            AddressCheckRes addressCheckRes = checkArea(IpUtil.getCityInfo(ip), machineRule.getDetail());
                            if (addressCheckRes != null) {
                                if (addressCheckRes.getType() == 2 && addressCheckRes.getScore() != null) {
                                    //灰名单
                                    machineRuleLogItem.setHitStatus(true);
                                    machineRuleLogItem.setScore(addressCheckRes.getScore());
                                    machineRuleLogItem.setNumber(addressCheckRes.getAddress());
                                    score = score.subtract(machineRuleLogItem.getScore());
                                } else if (addressCheckRes.getType() == 3) {
                                    //黑名单
                                    machineRuleLogItem.setHitStatus(true);
                                    machineRuleLogItem.setScore(machineRule.getSubScore());
                                    machineRuleLogItem.setNumber(addressCheckRes.getAddress());
                                    stop = true;
                                    score = score.subtract(machineRuleLogItem.getScore());
                                }
                                if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                                    stop = true;

                                    break;
                                }
                            }
                        }
                    }
                } else if ("hit_black".equals(machineRule.getRuleTag())) {
                    //黑名单库匹配
                    if (userByMybatis.getUserCheckRes() != null && JSON.isValidObject(userByMybatis.getUserCheckRes())) {
                        JSONObject userCheckJs = JSON.parseObject(userByMybatis.getUserCheckRes());
                        if (!userCheckJs.containsKey("rejectStatus")) {
                            userCheckJs.put("rejectStatus", false);
                        }

                        if (userCheckJs.getBoolean("ekaStatus") || userCheckJs.getBoolean("blackStatus") || userCheckJs.getBoolean("overdueStatus") || userCheckJs.getBoolean("rejectStatus")) {
                            machineRuleLogItem.setHitStatus(true);
                            machineRuleLogItem.setScore(machineRule.getSubScore());
                            machineRuleLogItem.setNumber("命中");

                            score = score.subtract(machineRule.getSubScore());

                            if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                                stop = true;
                            }
                        }
                    }
                } else if ("overdue_contact_check".equals(machineRule.getRuleTag())) {
//                    逾期订单联系人匹配
                    if (userByMybatis.getUserCheckRes() != null && JSON.isValidObject(userByMybatis.getUserCheckRes())) {
                        JSONObject userCheckJs = JSON.parseObject(userByMybatis.getUserCheckRes());
                        if (userCheckJs.getBoolean("contactStatus") != null && userCheckJs.getBoolean("contactStatus")) {
                            machineRuleLogItem.setHitStatus(true);
                            machineRuleLogItem.setScore(machineRule.getSubScore());
                            machineRuleLogItem.setNumber("命中");

                            score = score.subtract(machineRule.getSubScore());
                            if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                                stop = true;
                            }
                        }
                    }
                } else if ("gender_age".equals(machineRule.getRuleTag())) {
                    /**
                     * 性别年龄
                     */
                    if (machineRule.getDetail() == null || !JSON.isValidObject(machineRule.getDetail())) {
                        continue;
                    }
                    JSONObject detailJs = JSON.parseObject(machineRule.getDetail());
                    String ageStr = null;
                    if (userByMybatis.getGender() != null && userByMybatis.getAge() != null) {
                        if (userByMybatis.getGender() == 1 && detailJs.containsKey("boy")) {
                            //男
                            ageStr = detailJs.getString("boy");
                        } else if (userByMybatis.getGender() == 2 && detailJs.containsKey("girl")) {
                            //女
                            ageStr = detailJs.getString("girl");
                        }
                        if (StringUtils.hasText(ageStr) && ageStr.contains("-")) {
                            String[] ageArray = ageStr.split("-");
                            if (ageArray.length != 2) {
                                continue;
                            }
                            Integer startAge = Integer.parseInt(ageArray[0]);
                            Integer endAge = Integer.parseInt(ageArray[1]);

                            if (userByMybatis.getAge() < startAge || userByMybatis.getAge() > endAge) {
                                machineRuleLogItem.setHitStatus(true);
                                machineRuleLogItem.setScore(machineRule.getSubScore());
                                machineRuleLogItem.setNumber("性别:" + (userByMybatis.getGender() == 1 ? "男" : "女") + ",年龄:" + ageStr);

                                score = score.subtract(machineRule.getSubScore());
                                if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                                    stop = true;
                                }
                            }
                        }
                    }
                } else if ("contact_user_use".equals(machineRule.getRuleTag())) {
                    /**
                     * 紧急联系人匹配已注册会员数量
                     */
                    List<UserContactByMybatis> userContactByMybatisList = userContactByMybatisMapper.selectByUser(userByMybatis.getId());
                    if (userContactByMybatisList == null || userContactByMybatisList.size() <= 0) {
                        continue;
                    }
                    String mobile1 = null, mobile2 = null;
                    for (int i = 0; i < userContactByMybatisList.size(); i++) {
                        if (i == 0) {
                            mobile1 = userContactByMybatisList.get(i).getMobile();
                        } else if (i == 1) {
                            mobile2 = userContactByMybatisList.get(i).getMobile();
                        }
                    }
                    Integer hitNum = userContactByMybatisMapper.selectCountByMobile(mobile1, mobile2, userByMybatis.getId());
                    if (hitNum != null && hitNum > Integer.parseInt(machineRule.getDetail())) {
                        machineRuleLogItem.setHitStatus(true);
                        machineRuleLogItem.setScore(machineRule.getSubScore());
                        machineRuleLogItem.setNumber(hitNum + "");

                        score = score.subtract(machineRule.getSubScore());
                        if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                            stop = true;
                        }
                    }
                } else if ("order_time_interval".equals(machineRule.getRuleTag())) {
                    /**
                     * 同一用户申请订单间隔时间
                     */
                    LoanOrderByMybatis lastOrder = loanOrderByMybatisMapper.selectByLastSecond(userByMybatis.getId());
                    if (lastOrder != null && DateUtil.between(lastOrder.getCreateTime(), new Date(), DateUnit.DAY) < Integer.parseInt(machineRule.getDetail())) {
                        machineRuleLogItem.setHitStatus(true);
                        machineRuleLogItem.setScore(machineRule.getSubScore());
                        machineRuleLogItem.setNumber("" + DateUtil.between(lastOrder.getCreateTime(), new Date(), DateUnit.DAY));

                        score = score.subtract(machineRule.getSubScore());
                        if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                            stop = true;
                        }
                    }
                } else {
                    /**
                     * 其他自定义规则
                     */
                    String hitStatus = checkOtherRule(machineRule, reportJs);
                    if (StringUtils.hasLength(hitStatus)) {
                        machineRuleLogItem.setHitStatus(true);
                        machineRuleLogItem.setScore(machineRule.getSubScore());
                        machineRuleLogItem.setNumber(hitStatus);

                        score = score.subtract(machineRule.getSubScore());
                    }
                }
            }
            machineRuleLogItems.add(machineRuleLogItem);
        }
        boolean update = true;
        MachineRuleLogByMybatis machineRuleLog = machineRuleLogByMybatisMapper.selectByUserId(userId);
        if (machineRuleLog == null) {
            machineRuleLog = new MachineRuleLogByMybatis();
            machineRuleLog.setCreateTime(new Date());
            machineRuleLog.setUserId(userByMybatis.getId());
            update = false;
        }
        machineRuleLog.setScore(score);
        machineRuleLog.setRuleDetail(JSON.toJSONString(machineRuleLogItems));
        machineRuleLog.setUpdateTime(new Date());
        if (update) {
            machineRuleLogByMybatisMapper.updateByPrimaryKeySelective(machineRuleLog);
        } else {
            machineRuleLogByMybatisMapper.insertSelective(machineRuleLog);
        }

        if (stop) {
            //手动扣除风控余额
            rentalDataUtil.reportBalanceSub();
        }
        machineRes(setting, score, userByMybatis);
        return new ResResult(Code.SUCCESS, score);
    }


    private void machineRes(SettingByMybatis setting, BigDecimal score, UserByMybatis userByMybatis) {
        if (setting.getMachineAuto() != null && setting.getMachineAuto()) {
            //分数低于60分 自动拒绝操作
            LoanOrderByMybatis waitAuthOrder = loanOrderByMybatisMapper.selectByUserWaitAuth(userByMybatis.getId());
            if (waitAuthOrder != null) {
                LoanOrderByMybatis updateOrder = new LoanOrderByMybatis();
                updateOrder.setId(waitAuthOrder.getId());
                if (score.compareTo(BigDecimal.valueOf(60)) < 0) {
                    updateOrder.setStatus(OrderStatus.refuse.getStatus());
                } else {
                    updateOrder.setStatus(OrderStatus.wait_loan.getStatus());
                }
                loanOrderByMybatisMapper.updateByPrimaryKeySelective(updateOrder);

                String authBy = "机审管理员";
                if (waitAuthOrder.getAuthServiceId() != null) {
                    EruptUserByMybatis eruptUserByMybatis = eruptUserByMybatisMapper.selectByPrimaryKey(waitAuthOrder.getAuthServiceId());
                    if (eruptUserByMybatis != null) {
                        authBy = eruptUserByMybatis.getName();
                    }
                }

                //是否自动分配放款客服
                if (setting.getAutoAllocLoanService() != null && setting.getAutoAllocLoanService()) {
                    List<LoanOrderByMybatis> orderByMybatisList = new ArrayList<>();
                    orderByMybatisList.add(loanOrderByMybatisMapper.selectByPrimaryKey(waitAuthOrder.getId()));
                    //订单列表分配放款客服
                    eruptUserDataService.allotServiceByList(orderByMybatisList, ServiceType.loan_service);
                } else {
                    //通知放款客户
                    msgService.newMsgByOrder(NewMsgType.loan);
                }

                //插入一条审核记录
                LoanOrderAuthByMybatis loanOrderAuthByMybatis = new LoanOrderAuthByMybatis();
                loanOrderAuthByMybatis.setAuthBy(authBy);
                loanOrderAuthByMybatis.setOrderId(waitAuthOrder.getId());
                loanOrderAuthByMybatis.setAuthStatus(updateOrder.getStatus() != OrderStatus.refuse.getStatus().intValue());
                loanOrderAuthByMybatis.setOrderStatus(updateOrder.getStatus());
                loanOrderAuthByMybatis.setCreateTime(new Date());
                loanOrderAuthByMybatis.setReason("机审");
                loanOrderAuthByMybatisMapper.insertSelective(loanOrderAuthByMybatis);

                if (updateOrder.getStatus() == OrderStatus.wait_sign.getStatus().intValue()) {
                    //提交生成合同队列
//                    redisUtil.lpush(RedisCache.waitCreateContract, waitAuthOrder.getId() + "");
                } else if (updateOrder.getStatus() == OrderStatus.refuse.getStatus().intValue()) {
                    //拒绝后 给用户短信提醒
                    sysMsgUtil.sendAuthFail(userByMybatis.getMobile());
                }
                asyncService.notifyCheck(waitAuthOrder.getId());
            }
        }
        //用户风控状态修改
        UserByMybatis updateUser = new UserByMybatis();
        updateUser.setId(userByMybatis.getId());
        updateUser.setMachineStatus(score.compareTo(BigDecimal.valueOf(60)) >= 0);
        if (setting.getMachineAutoBlack() && score.compareTo(BigDecimal.valueOf(60)) < 0) {
            updateUser.setUserStatus(UserStatus.black.getType());
        }
        userByMybatisMapper.updateByPrimaryKeySelective(updateUser);
    }

    /**
     * 获取报告
     *
     * @param type
     * @param userByMybatis
     * @return
     */
    private UserReportByMybatis getUserReport(Integer type, UserByMybatis userByMybatis, SettingByMybatis setting) {
        if (!StringUtils.hasText(userByMybatis.getMobile()) || !StringUtils.hasText(userByMybatis.getCardNum())) {
            return null;
        }
        if (setting.getMachineAutoReport() != null && setting.getMachineAutoReport()) {
            //报告为空 且自动获取报告
            UserReportVo userReportVo = new UserReportVo();
            userReportVo.setUserId(userByMybatis.getId());
            userReportVo.setType(type);
            ResResult resResult = userReportService.getUserReport(userReportVo, false);
            if (resResult.getCode().intValue() == Code.SUCCESS.getCode()) {
                return (UserReportByMybatis) resResult.getData();
            }
        }
        return null;
    }


    @Transactional
    @Override
    public ResResult get(Long userId) {
        MachineRuleLogByMybatis machineRuleLogByMybatis = machineRuleLogByMybatisMapper.selectByUserId(userId);
        return new ResResult(Code.SUCCESS, machineRuleLogByMybatis);
    }

    /**
     * 比较值  true：命中   false:未命中
     *
     * @param number    不能超过的值
     * @param dataField 数据字段
     * @param dataJs    数据json
     * @param direction true:>=    false:<=
     * @return
     */
    public String compareData(BigDecimal number, String dataField, JSONObject dataJs, boolean direction) {
        if (dataJs == null) {
            return "无数据";
        }
        JSONObject tempJs = dataJs;
        String[] dataFieldArray = dataField.split("\\.");
        for (int i = 0; i < dataFieldArray.length; i++) {
            String key = dataFieldArray[i];
            if (!StringUtils.hasLength(key)) {
                continue;
            }
            if (!tempJs.containsKey(key)) {
                return null;
            }
            if (i == dataFieldArray.length - 1) {
                //最后一个
                BigDecimal dataNum = tempJs.getBigDecimal(key);
                if (direction && dataNum.compareTo(number) > 0) {
                    return dataNum + "";
                } else if (!direction && dataNum.compareTo(number) < 0) {
                    return dataNum + "";
                }
            } else {
                tempJs = tempJs.getJSONObject(key);
            }
        }
        return null;
    }


    /**
     * 其他规则处理
     *
     * @param machineRule
     * @param reportJs
     * @return 不为null 则命中
     */
    public String checkOtherRule(MachineRuleByMybatis machineRule, JSONObject reportJs) {
        if (reportJs == null) {
            return "无数据";
        }
        if ("tanzhen_latest_performance_time".equals(machineRule.getRuleTag())) {
            /**
             * 探针-最近履约时间距今月份
             */
            if (reportJs.containsKey("latest_performance_time")) {
                String latest_performance_time = reportJs.getString("latest_performance_time");
                String[] monthArray = latest_performance_time.split("-");
                if (monthArray.length != 2) {
                    return null;
                }
                // 目标年月
                YearMonth target = YearMonth.of(Integer.parseInt(monthArray[0]), Integer.parseInt(monthArray[1]));
                // 当前年月
                YearMonth current = YearMonth.now();
                // 计算月份差
                long monthsBetween = ChronoUnit.MONTHS.between(current, target);
                if (Math.abs(monthsBetween) > Integer.parseInt(machineRule.getDetail())) {
                    return Math.abs(monthsBetween) + "";
                }
            }
        } else if ("platform_1_query_rate".equals(machineRule.getRuleTag())) {
            /**
             * 近一个月机构查询次数占总查询次数比例
             */
            if (!reportJs.containsKey("apply_report_detail")) {
                return null;

            }
            JSONObject apply_report_detail = reportJs.getJSONObject("apply_report_detail");
            if (apply_report_detail == null || !apply_report_detail.containsKey("A22160006") || !apply_report_detail.containsKey("A22160008")) {
                return null;
            }
            Integer total = apply_report_detail.getInteger("A22160006");
            total = total == 0 ? 1 : total;
            Integer month_1 = apply_report_detail.getInteger("A22160008");

            BigDecimal rate = BigDecimal.valueOf(month_1).divide(BigDecimal.valueOf(total), 4, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100));
            if (rate.compareTo(new BigDecimal(machineRule.getDetail())) > 0) {
                return "" + rate;
            }
        } else if ("tanzhen_result_2".equals(machineRule.getRuleTag())) {
            /**
             * 探针C探查结果非正常履约
             */
            if (!reportJs.containsKey("result_code")) {
                return null;
            }
            if (!"2".trim().equals(reportJs.getString("result_code"))) {
                return reportJs.getString("result_code");
            }
        } else if ("loan_and_apply_zhixin".equals(machineRule.getRuleTag())) {
            /**
             * 贷款行为等于且申请准入置信度分小于命中
             */
            if (!reportJs.containsKey("behavior_report_detail") || !reportJs.containsKey("apply_report_detail")) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());
            if (!detailJs.containsKey("x") || !detailJs.containsKey("y")) {
                return null;
            }

            Integer loan_score = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170001");
            Integer zhixin = reportJs.getJSONObject("apply_report_detail").getInteger("A22160002");
            if (loan_score == null || zhixin == null) {
                return null;
            }

            if (loan_score < detailJs.getInteger("x") && zhixin < detailJs.getInteger("y")) {
                return "1";
            }
        } else if ("pay_rate_apply_zhixin".equals(machineRule.getRuleTag())) {
            /**
             * 正常还款订单数占贷款总订单数比例 < x且申请准入置信度 < y
             */
            if (!reportJs.containsKey("behavior_report_detail") || !reportJs.containsKey("apply_report_detail")) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());
            if (!detailJs.containsKey("x") || !detailJs.containsKey("y")) {
                return null;
            }

            Integer pay_all_rate = null;
            String rate = reportJs.getJSONObject("behavior_report_detail").getString("B22170034");
            if (StringUtils.hasLength(rate) && rate.contains("%")) {
                rate = rate.replaceAll("%", "");
                pay_all_rate = Integer.parseInt(rate);
            }
            Integer zhixin = reportJs.getJSONObject("apply_report_detail").getInteger("A22160002");
            if (pay_all_rate == null || zhixin == null) {
                return null;
            }

            if (pay_all_rate < detailJs.getInteger("x") && zhixin < detailJs.getInteger("y")) {
                return "1";
            }
        } else if ("loan_b_score".equals(machineRule.getRuleTag())) {
            /**
             * 贷款行为分不在区间内 拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            Integer loan_score = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170001");
            if (loan_score == null) {
                return null;
            }

            Integer start = Integer.parseInt(machineRule.getDetail().split("-")[0]);
            Integer end = Integer.parseInt(machineRule.getDetail().split("-")[1]);

            if (loan_score < start || loan_score > end) {
                return "1";
            }
        } else if ("leida_pay_rate".equals(machineRule.getRuleTag())) {
            /**
             * 正常还款订单数占贷款总订单数⽐例
             */
            if (reportJs.containsKey("behavior_report_detail")) {
                JSONObject behavior_report_detail = reportJs.getJSONObject("behavior_report_detail");
                if (behavior_report_detail != null && behavior_report_detail.containsKey("B22170034")) {
                    String rate = behavior_report_detail.getString("B22170034");
                    if (StringUtils.hasLength(rate) && rate.contains("%")) {
                        rate = rate.replaceAll("%", "");
                        Double rateNum = Double.valueOf(rate);
                        String detailStr = machineRule.getDetail();
                        if (detailStr != null && rateNum < Double.parseDouble(detailStr)) {
                            return rate;
                        }
                    }
                }
            }
        } else if ("loan_score_rate_fail".equals(machineRule.getRuleTag())) {
            /**
             * 贷款行为分=s 且正常还款订单数占贷款总订单数比例 < x ，且失败扣款笔数 > y，且履约贷款次数 < z ，拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail") || !reportJs.containsKey("apply_report_detail")) {
                return null;
            }
            JSONObject behavior_report_detail = reportJs.getJSONObject("behavior_report_detail");
            if (behavior_report_detail != null && behavior_report_detail.containsKey("B22170034")) {
                return null;
            }

            if (behavior_report_detail != null && behavior_report_detail.containsKey("B22170001")) {
                return null;
            }

            //正常还款订单数占总订单数比例
            Integer pay_all_rate = null;
            String rate = behavior_report_detail.getString("B22170034");
            if (StringUtils.hasLength(rate) && rate.contains("%")) {
                rate = rate.replaceAll("%", "");
                pay_all_rate = Integer.parseInt(rate);
            }
            //贷款行为分
            Integer loan_score = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170001");
            //失败扣款笔数
            Integer pay_fail = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170035");
            //履约贷款次数
            Integer pay_success = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170045");

            if (pay_all_rate == null || loan_score == null || pay_fail == null || pay_success == null) {
                return null;
            }

            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());
            if (loan_score == detailJs.getInteger("s").intValue() && pay_all_rate < detailJs.getInteger("x")
                    && pay_fail > detailJs.getInteger("y") && pay_success < detailJs.getInteger("z")) {
                return "1";
            }
        } else if ("month_1_pay_success_fail".equals(machineRule.getRuleTag())) {
            /**
             * 近1个月履约贷款次数 < x，且近1个月履约贷款次数-近1个月失败扣款笔数 < y
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());
            if (!detailJs.containsKey("x") || !detailJs.containsKey("y")) {
                return null;
            }

            Integer month_pay_success = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170045");
            Integer month_pay_fail = reportJs.getJSONObject("behavior_report_detail").getInteger("B22170035");
            if (month_pay_fail == null || month_pay_success == null) {
                return null;
            }
            if (month_pay_success < detailJs.getInteger("x") && (month_pay_success - month_pay_fail) < detailJs.getInteger("y")) {
                return "1";
            }
        } else if ("max_performance_amt".equals(machineRule.getRuleTag())) {
            /**
             * 最大履约金额 < x  拒绝
             */
            if (!reportJs.containsKey("max_performance_amt")) {
                return null;
            }
            BigDecimal amt_x = new BigDecimal(machineRule.getDetail());
            String max_performance_amt = reportJs.getString("max_performance_amt");
            BigDecimal star = BigDecimal.ZERO;
            if (max_performance_amt.contains("-")) {
                star = new BigDecimal(max_performance_amt.split("-")[0]);
            } else {
                star = new BigDecimal(max_performance_amt);
            }
            if (star.compareTo(amt_x) < 0) {
                return max_performance_amt;
            }
        } else if ("month_1_loan_money".equals(machineRule.getRuleTag())) {
            /**
             * 近1个月履约贷款总⾦额 < x 拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            String B22170040 = reportJs.getJSONObject("behavior_report_detail").getString("B22170040");
            if (!StringUtils.hasLength(B22170040)) {
                return null;
            }
            B22170040 = B22170040.replace("[", "");
            B22170040 = B22170040.replace("]", "");
            B22170040 = B22170040.replace(")", "");
            B22170040 = B22170040.replace("(", "");
            BigDecimal amt_x = new BigDecimal(machineRule.getDetail());
            BigDecimal star = BigDecimal.ZERO;
            if (B22170040.contains(",")) {
                star = new BigDecimal(B22170040.split(",")[0]);
            } else {
                star = new BigDecimal(B22170040);
            }
            if (star.compareTo(amt_x) < 0) {
                return B22170040;
            }
        } else if ("month_6_overdue_money".equals(machineRule.getRuleTag())) {
            /**
             * 近6个月累计逾期金额>x 拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            String B22170031 = reportJs.getJSONObject("behavior_report_detail").getString("B22170031");
            if (!StringUtils.hasLength(B22170031)) {
                return null;
            }
            B22170031 = B22170031.replace("[", "");
            B22170031 = B22170031.replace("]", "");
            B22170031 = B22170031.replace(")", "");
            B22170031 = B22170031.replace("(", "");
            BigDecimal amt_x = new BigDecimal(machineRule.getDetail());
            BigDecimal star = BigDecimal.ZERO;
            if (B22170031.contains(",")) {
                star = new BigDecimal(B22170031.split(",")[0]);
            } else {
                star = new BigDecimal(B22170031);
            }
            if (star.compareTo(amt_x) > 0) {
                return B22170031;
            }
        } else if ("leida_latest_performance_time".equals(machineRule.getRuleTag())) {
            /**
             * 最近一次履约距今天数
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            String B22170050 = reportJs.getJSONObject("behavior_report_detail").getString("B22170050");
            if (!StringUtils.hasLength(B22170050)) {
                return null;
            }
            B22170050 = B22170050.replace("[", "");
            B22170050 = B22170050.replace("]", "");
            B22170050 = B22170050.replace("(", "");
            B22170050 = B22170050.replace(")", "");
            BigDecimal amt_x = new BigDecimal(machineRule.getDetail());
            BigDecimal start = BigDecimal.ZERO;
            if (B22170050.contains(",")) {
                start = new BigDecimal(B22170050.split(",")[0]);
            } else {
                start = new BigDecimal(B22170050);
            }
            if (start.compareTo(amt_x) >= 0) {
                return B22170050;
            }
        } else if (machineRule.getRuleTag().contains("month_pay_fail_13_")) {
            /**
             * 近1个月失败扣款笔数>X 且近1个月失败扣款笔数÷近3个月失败扣款笔数>X%，拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            //近1个月失败扣款笔数
            String B22170050 = reportJs.getJSONObject("behavior_report_detail").getString("B22170035");
            if (!StringUtils.hasLength(B22170050)) {
                return null;
            }
            //近3个月失败扣款笔数
            String B22170036 = reportJs.getJSONObject("behavior_report_detail").getString("B22170036");
            if (!StringUtils.hasLength(B22170036)) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());

            BigDecimal B22170050_1 = new BigDecimal(B22170050);
            BigDecimal B22170036_3 = new BigDecimal(B22170036);
            BigDecimal rate = B22170050_1.divide(B22170036_3.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : B22170036_3, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100));
            if (B22170050_1.compareTo(detailJs.getBigDecimal("x")) > 0 && rate.compareTo(detailJs.getBigDecimal("x")) > 0) {
                return B22170050_1 + "--" + B22170036_3 + "--" + rate;
            }
        } else if (machineRule.getRuleTag().contains("month_pay_fail_36")) {
            /**
             * 近3个月失败扣款笔数>X 且近3个月失败扣款笔数÷近6个月失败扣款笔数>X%，拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            //近3个月失败扣款笔数
            String B22170050 = reportJs.getJSONObject("behavior_report_detail").getString("B22170036");
            if (!StringUtils.hasLength(B22170050)) {
                return null;
            }
            //近6个月失败扣款笔数
            String B22170036 = reportJs.getJSONObject("behavior_report_detail").getString("B22170037");
            if (!StringUtils.hasLength(B22170036)) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());
            BigDecimal B22170050_1 = new BigDecimal(B22170050);
            BigDecimal B22170036_3 = new BigDecimal(B22170036);
            BigDecimal rate = B22170050_1.divide(B22170036_3.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : B22170036_3, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100));
            if (B22170050_1.compareTo(detailJs.getBigDecimal("x")) > 0 && rate.compareTo(detailJs.getBigDecimal("x")) > 0) {
                return B22170050_1 + "--" + B22170036_3 + "--" + rate;
            }
        } else if (machineRule.getRuleTag().contains("month_pay_fail_112_")) {
            /**
             * 近1个月失败扣款笔数>X 且近1个月失败扣款笔数÷近12个月失败扣款笔数>X%，拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            //近1个月失败扣款笔数
            String B22170050 = reportJs.getJSONObject("behavior_report_detail").getString("B22170035");
            if (!StringUtils.hasLength(B22170050)) {
                return null;
            }
            //近12个月失败扣款笔数
            String B22170036 = reportJs.getJSONObject("behavior_report_detail").getString("B22170038");
            if (!StringUtils.hasLength(B22170036)) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());

            BigDecimal B22170050_1 = new BigDecimal(B22170050);
            BigDecimal B22170036_3 = new BigDecimal(B22170036);
            BigDecimal rate = B22170050_1.divide(B22170036_3.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : B22170036_3, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100));
            if (B22170050_1.compareTo(detailJs.getBigDecimal("x")) > 0 && rate.compareTo(detailJs.getBigDecimal("x")) > 0) {
                return B22170050_1 + "--" + B22170036_3 + "--" + rate;
            }
        } else if (machineRule.getRuleTag().contains("month_pay_fail_312_")) {
            /**
             * 近3个月失败扣款笔数>X 且近3个月失败扣款笔数÷近12个月失败扣款笔数>X%，拒绝
             */
            if (!reportJs.containsKey("behavior_report_detail")) {
                return null;
            }
            //近3个月失败扣款笔数
            String B22170036 = reportJs.getJSONObject("behavior_report_detail").getString("B22170036");
            if (!StringUtils.hasLength(B22170036)) {
                return null;
            }
            //近12个月失败扣款笔数
            String B22170038 = reportJs.getJSONObject("behavior_report_detail").getString("B22170038");
            if (!StringUtils.hasLength(B22170038)) {
                return null;
            }
            JSONObject detailJs = JSON.parseObject(machineRule.getDetail());

            BigDecimal B22170050_1 = new BigDecimal(B22170036);
            BigDecimal B22170036_3 = new BigDecimal(B22170038);
            BigDecimal rate = B22170050_1.divide(B22170036_3.compareTo(BigDecimal.ZERO) == 0 ? BigDecimal.ONE : B22170036_3, RoundingMode.DOWN).multiply(BigDecimal.valueOf(100));
            if (B22170050_1.compareTo(detailJs.getBigDecimal("x")) > 0 && rate.compareTo(detailJs.getBigDecimal("x")) > 0) {
                return B22170050_1 + "--" + B22170036_3 + "--" + rate;
            }
        }
        return null;
    }

    /**
     * 校验地址黑白名单
     *
     * @param address
     * @param ruleDetail
     * @return 1:白名单   2：灰名单   3：黑名单
     */
    private AddressCheckRes checkArea(String address, String ruleDetail) {
        JSONObject detailJs = JSON.parseObject(ruleDetail);
        if (detailJs.containsKey("white")) {
            String whiteStr = detailJs.getString("white");
            if (StringUtils.hasLength(whiteStr)) {
                String[] areas = whiteStr.split(",");
                for (String area : areas) {
                    String[] array = area.split("@");
                    boolean checkStatus = false;
                    for (String item : array) {
                        if (!StringUtils.hasLength(item)) {
                            continue;
                        }
                        if (address.contains(item)) {
                            checkStatus = true;
                        } else {
                            checkStatus = false;
                        }
                    }
                    if (checkStatus) {
                        return new AddressCheckRes(1, null, null);
                    }
                }
            }
        }

        if (detailJs.containsKey("gray") && detailJs.containsKey("grayScore")) {
            String grayStr = detailJs.getString("gray");
            if (StringUtils.hasLength(grayStr)) {
                String[] areas = grayStr.split(",");
                for (String area : areas) {
                    String[] array = area.split("@");
                    boolean checkStatus = true;
                    for (String item : array) {
                        if (!StringUtils.hasLength(item)) {
                            continue;
                        }
                        if (!address.contains(item)) {
                            checkStatus = false;
                        }
                    }
                    if (checkStatus) {
                        return new AddressCheckRes(2, address, detailJs.getBigDecimal("grayScore"));
                    }
                }
            }
        }

        if (detailJs.containsKey("black")) {
            String blackStr = detailJs.getString("black");
            if (StringUtils.hasLength(blackStr)) {
                String[] areas = blackStr.split(",");
                for (String area : areas) {
                    String[] array = area.split("@");
                    boolean checkStatus = true;
                    for (String item : array) {
                        if (!StringUtils.hasLength(item)) {
                            continue;
                        }
                        if (!address.contains(item)) {
                            checkStatus = false;
                        }
                    }
                    if (checkStatus) {
                        return new AddressCheckRes(3, address, null);
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取运营商手机使用时间（月
     * <p>
     * '1': '[0,3）',
     * '2': '[3,6）',
     * '3': '[6,12）',
     * '4': '[12,24）',
     * '5': '[24,+)',
     * '0': '查无此号或已注销',
     * '-1': '不支持该运营商',
     * '999': '手机状态异常（注:1、销号6月以上；2、携号转网；3、未放出去的号码）；非本网手机号码'
     * ）
     *
     * @param time_online
     * @return
     */
    private Integer getMobileTimeOnline(Integer time_online) {
        if (time_online == null) {
            return 0;
        }
        if (time_online == 1) {
            return 2;
        } else if (time_online == 2) {
            return 5;
        } else if (time_online == 3) {
            return 11;
        } else if (time_online == 4) {
            return 23;
        } else if (time_online == 5) {
            return 36;
        }
        return 0;
    }

    private String getDataType(String dateType) {
        if ("cpws".trim().equals(dateType)) {
            return "裁判文书";
        } else if ("ktgg".trim().equals(dateType)) {
            return "开庭公告";
        } else if ("ajlc".trim().equals(dateType)) {
            return "案件流程信息";
        } else if ("fygg".trim().equals(dateType)) {
            return "法院公告";
        } else if ("shixin".trim().equals(dateType)) {
            return "失信公告";
        } else if ("zxgg".trim().equals(dateType)) {
            return "执行公告";
        } else if ("bgt".trim().equals(dateType)) {
            return "曝光台";
        }
        return "";
    }

}
